A common debugger has the following basic functions: interrupting a running program by making a target program trigger an abnormity, and executing the target program according to a user's will; looking up software runtime information, such information including, but not limited to, register information and memory information of the current thread; and modifying software execution flows, including: modifying memory information, register information, etc.
The working principle of the debugger is that based on an abnormal mechanism of a central processor, an abnormity distribution (or event distribution) sub-system of an operating system is responsible for packaging the abnormity (or event), and then performing a real-time interaction with the debugger in a relatively friendly manner. When the debugger captures an abnormity (or event), it will determine whether it is necessary to take over the abnormity (or event) based on the inherent logic of the debugger and then it will determine which function of the debugger takes it over. After the debugger takes over this abnormity (or event), further processing will be made as required by the user, and after completion of the processing, the system is notified that the processing is completed, and then a new round of abnormity (or event) capturing and distribution will be started.
During the process of program debugging, a programmer usually has to know whether he/she has gone too far in program debugging, whether the execution result of a previous step is right, and so on, which needs to use a reverse debugging technique. Reverse debugging is a debugging scheme in a debugger. This scheme allows a program to return to historical points where the program has been executed. At present, debuggers providing a reverse debugging function include: TotalView Debugger of TotalView Technologies, and GDB of an open source community.
Theoretically, if a program intends to return to a historical point where it has been executed, the state of the historical point should be recorded, including memory values and register values related to the historical point and the program. The existing schemes for implementing reverse debugging functions either require too much memory space or take too much time to reach a reverse target breakpoint.